# coding:utf-8
import json
import requests
from flask import Blueprint, session
from flask import render_template, request, current_app, redirect, \
    url_for, flash
from flask_login import login_user, current_user, login_required, logout_user

from common.file_util import upload_file
from common.oss import conn_bucket
from settings import Config
from xshare.forms.forms import AccessForm, CreateClubForm, UpdateClubForm, \
    CreatePostForm, UpdatePostForm, UserProfileForm, MessageForm, \
    UpdatePasswordForm
from xshare.model.about import About
from xshare.model.access_record import AccessRecord
from xshare.model.club import Club
from xshare.model.message import Message
from xshare.model.post import Post
from xshare.model.user import User

main = Blueprint('main', __name__)


class TMss:
    def __init__(self, msg, url):
        self.msg = msg
        self.url = url


def create_access_record(club, accessor_id):
    res, access_record = AccessRecord.insert_record(club, accessor_id)
    return res


@main.route('/')
def index():
    page = request.args.get('page', 1, type=int)
    pagination = Club.query.filter_by(is_deleted=0). \
        order_by(Club.create_time.desc()). \
        paginate(page, per_page=current_app.config['CLUB_PER_PAGE'],
                 error_out=False)
    club_list = pagination.items
    return render_template('front/home.html', club_list=club_list,
                           pagination=pagination, endpoint='.index')


@main.route('/access/club/<int:club_id>', methods=["GET", "POST"])
def access_club(club_id):
    if not current_user.is_authenticated:
        return redirect(url_for('main.login'))
    club = Club.get_by_id(int(club_id))
    if not club:
        flash(u'俱乐部不存在！', 'danger')
        return redirect(url_for('main.index'))
    form = AccessForm()
    access_key = 'access_key_' + f'{current_user.id}' + f'_{club_id}'
    if form.validate_on_submit():
        access_password = request.form.get("password")
        check_res = club.verify_password(access_password)
        if not check_res:
            flash(u'密码不正确！', 'danger')
            return redirect(url_for('main.access_club', club_id=club_id))
        session[access_key] = access_password
        res, access_record = AccessRecord.insert_record(club, current_user.id)
        return redirect(url_for('main.club_post_list', club_id=club.id))
    # 用户之前已经访问过，直接进入页面，如果该俱乐部是当前用户的所有者，直接进入
    access_password = session.get(access_key)
    if club.author_id == current_user.id or \
            (access_password and club.verify_password(access_password)):
        pagination = Post.query.filter_by(is_deleted=0, club_id=club.id). \
            order_by(Post.create_time.desc()). \
            paginate(1, per_page=current_app.config['CLUB_PER_PAGE'],
                     error_out=False)
        # 这一步可能会报错，需要处理一下
        post_list = pagination.items
        if club.author_id != current_user.id:
            res, access_record = AccessRecord.insert_record(club,
                                                            current_user.id)
        return render_template('front/post_list.html', post_list=post_list,
                               pagination=pagination,
                               page=1,
                               club_id=club_id,
                               endpoint='main.club_post_list')
    return render_template('front/club_access.html', form=form, club=club)


@main.route('/post/list/<int:club_id>', methods=["GET"])
def club_post_list(club_id):
    if not current_user.is_authenticated:
        return redirect(url_for('main.login'))
    club = Club.get_by_id(int(club_id))
    if not club:
        flash(u'俱乐部不存在！', 'danger')
        return redirect(url_for('main.access_club', club_id=club_id))
    access_key = 'access_key_' + 'user_id_' + f'{club.id}'
    access_password = session.get(access_key)
    if not access_password:
        flash(u'请重新输入访问密码！', 'danger')
        return redirect(url_for('main.access_club', club_id=club_id))
    check_res = club.verify_password(access_password)
    if not check_res:
        flash(u'密码不正确！', 'danger')
        return redirect(url_for('main.access_club', club_id=club_id))
    page = request.args.get('page', 1, type=int)
    pagination = Post.query.filter_by(is_deleted=0). \
        order_by(Post.create_time.desc()). \
        paginate(page, per_page=current_app.config['POST_PER_PAGE'],
                 error_out=False)
    # 这一步可能会报错，需要处理一下
    post_list = pagination.items
    endpoint = url_for('main.club_post_list', club_id=club_id)
    return render_template('front/post_list.html', post_list=post_list,
                           pagination=pagination,
                           endpoint='main.club_post_list',
                           club_id=club_id)


@main.route('/create/club/', methods=["GET", "POST"])
@login_required
def create_club():
    club_count = Club.query.filter_by(author_id=current_user.id,
                                      is_deleted=0).count()
    if club_count >= 5:
        tmss = TMss(u"您的俱乐部个数已达最大数<span>5</span>个", url_for('main.user_center'))
        return render_template('front/warning.html', tmss=tmss)
    form = CreateClubForm()
    if form.validate_on_submit():
        name = form.data.get("name")
        password = form.data.get("password")
        desc = form.data.get("desc")
        res, club = Club.insert_club(
            name=name,
            access_password=password,
            introduction=desc,
            author_id=current_user.id
        )
        if res:
            flash(u'创建成功！', 'success')
            return redirect(url_for('main.user_center'))
        else:
            flash(u'创建失败！', 'danger')
            return redirect(url_for('main.create_club'))
    return render_template("front/create_club.html", form=form)


@main.route('/user/clubs/', methods=["GET"])
def user_clubs():
    page = request.args.get('page', 1, type=int)
    user_id = request.args.get('user_id', None, type=int)
    if not user_id:
        return redirect(url_for('main.index'))
    pagination = Club.query.filter_by(is_deleted=0,
                                      author_id=int(user_id)). \
        order_by(Club.create_time.desc()). \
        paginate(page, per_page=current_app.config['CLUB_PER_PAGE'],
                 error_out=False)
    club_list = pagination.items
    user = User.get_by_id(user_id)
    return render_template('front/clubs.html', club_list=club_list, user=user,
                           page=page,
                           pagination=pagination, endpoint='main.user_clubs')


@main.route('/update/club/', methods=["GET", "POST"])
@login_required
def update_club():
    if request.method == "GET":
        club_id = request.args.get("club_id")
        club = Club.get_by_id(int(club_id))
        if not club:
            flash(u'俱乐部不存在！', 'danger')
            return redirect(url_for('main.user_center'))
        form = UpdateClubForm(name=club.name, password='',
                              club_id=club_id,
                              desc=club.introduction)
        return render_template('front/update_club.html', form=form)
    else:
        form = UpdateClubForm()
        club_id = None
        club_id = form.data.get("club_id")
        name = form.data.get("name")
        password = form.data.get("password")
        desc = form.data.get("desc")
        club = Club.get_by_id(int(club_id))
        update_dict = {
            "name": name,
            "introduction": desc,
            "author_id": current_user.id
        }
        if password:
            update_dict.update({"access_password": password})

        res, msg, club = club.update(entry_id=club.id, parameters=update_dict)
        if res:
            flash(u'更新成功！', 'success')
            return redirect(url_for('main.user_center'))
        else:
            flash(u'更新失败！', 'danger')
            return redirect(url_for('main.update_club', club_id=club_id))
        # return redirect(url_for('main.update_club', club_id=club_id))


@main.route('/create/post/', methods=["GET", "POST"])
@login_required
def create_post():
    form = CreatePostForm()
    form.club_id.choices = [(g.id, g.name) for g in
                            Club.query.filter_by(author_id=current_user.id).
                            order_by('name')]
    if form.validate_on_submit():
        title = form.data.get("title")
        content = form.data.get("content")
        club_id = form.data.get("club_id")
        res, msg, club = Post.create({
            "title": title,
            "club_id": club_id,
            "content":  content,
            "author_id": current_user.id
        })
        if res:
            flash(u'创建成功！', 'success')
            return redirect(url_for('main.user_post'))
        else:
            flash(u'创建失败！', 'danger')
            return redirect(url_for('main.create_post'))
    return render_template("front/create_post.html", form=form)


@main.route('/update/post/', methods=["GET", "POST"])
@login_required
def update_post():
    if request.method == "GET":
        post_id = request.args.get("post_id")
        post = Post.get_by_id(int(post_id))
        if not post:
            flash(u'俱乐部不存在！', 'danger')
            return redirect(url_for('main.user_center'))
        form = UpdatePostForm(title=post.title,
                              content=post.content,
                              club_id=post.club_id,
                              post_id=post.id)
        form.club_id.choices = [(g.id, g.name) for g in
                                Club.query.filter_by(author_id=current_user.id)
                                .order_by('name')]
        return render_template('front/update_post.html', form=form)
    else:
        form = UpdatePostForm()
        post_id = form.data.get("post_id")
        club_id = form.data.get("club_id")
        title = form.data.get("title")
        content = form.data.get("content")
        post = Post.get_by_id(int(post_id))
        update_dict = {
            "title": title,
            "content": content,
            "club_id": club_id
        }

        res, msg, club = post.update(entry_id=post.id, parameters=update_dict)
        if res:
            flash(u'更新成功！', 'success')
            return redirect(url_for('main.user_post'))
        else:
            flash(u'更新失败！', 'danger')
            return redirect(url_for('main.update_post', club_id=club_id))


@main.route('/update/pwd/', methods=["GET", "POST"])
@login_required
def update_pwd():
    form = UpdatePasswordForm()
    if request.method == "GET":
        return render_template('front/update_pwd.html', form=form)
    else:
        if form.validate_on_submit():
            password = form.data.get("password")
            user = User.get_by_id(int(current_user.id))
            password_hash = user.hash_password(password)
            res, msg, user = user.\
                update(entry_id=user.id,
                       parameters={"password_hash": password_hash})
            if res:
                flash(u'更新成功！', 'success')
                return redirect(url_for('main.update_pwd'))
            else:
                flash(u'更新失败！', 'danger')
                return redirect(url_for('main.update_pwd'))
        return redirect(url_for('main.update_pwd'))


@main.route('/guest/book/', methods=["GET", "POST"])
@login_required
def guest_book():
    form = MessageForm()
    if request.method == "GET":
        page = request.args.get("page", 1)
        pagination = Message.query.filter_by(is_deleted=0). \
            order_by(Message.create_time.desc()). \
            paginate(page, per_page=current_app.config['POST_PER_PAGE'],
                     error_out=False)
        # 这一步可能会报错，需要处理一下
        messages_list = pagination.items
        return render_template('front/messages.html', form=form,
                               messages_list=messages_list)
    else:
        if form.validate_on_submit():
            msg_type = form.data.get("msg_type")
            content = form.data.get("content")
            create_dict = {
                "author_id": current_user.id,
                "msg_type": msg_type,
                "content": content,
            }

            res, msg, message = Message.create(parameters=create_dict)
            if res:
                flash(u'提交成功！', 'success')
                return redirect(url_for('main.guest_book'))
            else:
                flash(u'提交失败！', 'danger')
                return redirect(url_for('main.guest_book'))
        messages_list = Message.get_list()
        return render_template('front/messages.html', form=form,
                               messages_list=messages_list)


@main.route('/user/center/', methods=["GET"])
@login_required
def user_center():
    page = request.args.get('page', 1, type=int)
    pagination = Club.query.filter_by(is_deleted=0,
                                      author_id=current_user.id). \
        order_by(Club.create_time.desc()). \
        paginate(page, per_page=current_app.config['CLUB_PER_PAGE'],
                 error_out=False)
    club_list = pagination.items
    user = User.get_by_id(current_user.id)
    return render_template('front/user_center.html', club_list=club_list, user=user,
                           pagination=pagination, endpoint='main.user_center')


@main.route('/access/record/', methods=["GET"])
@login_required
def club_access_record():
    page = request.args.get('page', 1, type=int)
    user_id = request.args.get('user_id', 1, type=int)
    pagination = AccessRecord.query.filter_by(is_deleted=0,
                                              club_author_id=user_id). \
        order_by(AccessRecord.create_time.desc()). \
        paginate(page, per_page=current_app.config['ACCESS_RECORD_PER_PAGE'],
                 error_out=False)
    club_access_list = pagination.items
    user = User.get_by_id(current_user.id)
    return render_template('front/access_record.html', club_access_list=club_access_list,
                           user=user,
                           pagination=pagination, endpoint='main.club_access_record')


@main.route('/user/profile/', methods=["GET"])
@login_required
def user_profile():
    form = UserProfileForm()
    user = User.get_by_id(current_user.id)
    if request.method == "GET":
        if user.avatar_hash is None or user.avatar_hash == '':
            res, user = user.update_avatar(user, user.email)
        form.username.data = user.username
        form.gender.default = user.gender
        return render_template('front/user_profile.html', form=form, user=user)
    else:
        if form.validate_on_submit():
            username = form.data.get("username")
            gender = form.data.get("gender")
            res, msg, user = user.update(current_user.id, {"username": username,
                                        "gender": int(gender)})
            if res:
                flash(u'更新成功！', 'success')
                return redirect(url_for('main.user_center'))
            else:
                flash(u'更新失败！', 'danger')
                return redirect(url_for('main.user_profile'))
        return redirect(url_for('main.user_profile'))


@main.route('/user/post/', methods=["GET"])
@login_required
def user_post():
    page = request.args.get('page', 1, type=int)
    pagination = Post.query.filter_by(is_deleted=0, author_id=current_user.id). \
        order_by(Post.create_time.desc()). \
        paginate(page, per_page=current_app.config['USER_POST_PER_PAGE'],
                 error_out=False)
    # 这一步可能会报错，需要处理一下
    post_list = pagination.items
    user_club_list = Club.query.filter_by(is_deleted=0, author_id=current_user.id).all()
    return render_template('front/user_post.html', post_list=post_list,
                           pagination=pagination,
                           user_club_list=user_club_list,
                           endpoint='main.user_post')


@main.route('/search/', methods=['GET'])
def search_list():
    page = request.args.get('page', 1, type=int)
    content = request.args.get('content')
    pagination = Club.query.filter(
        Club.name.ilike('%' + content + '%')).order_by(
        Club.create_time.desc()).paginate(
        page, per_page=current_app.config['CLUB_PER_PAGE'],
        error_out=False)
    club_list = pagination.items

    return render_template('front/list.html', club_list=club_list,
                           pagination=pagination,
                           endpoint='.search_list', content=content)


@main.route('/user/password/', methods=["GET"])
@login_required
def user_password():

    return render_template('front/user_password.html')


@main.route('/login/', methods=["GET", "POST"])
def login():
    if request.method == "GET":
        return render_template('front/login.html')
    email = request.form.get("email", None)
    password = request.form.get("password", None)
    if not email or not password:
        flash(u'用户名和密码不能为空!', 'danger')
        return render_template('admin/login.html')
    user = User.query.filter_by(email=email, is_deleted=0).first()
    if user is not None and user.verify_password(password):
        login_user(user)
        user_ip = request.environ.get('HTTP_X_REAL_IP', request.remote_addr)
        try:
            user.ip = user_ip
            res = requests.get(f"https://ip.taobao.com/service/getIpInfo.php?ip={user_ip}")
            user.update(user.id, {"ip": user_ip})
        except:
            pass
        flash(u'登陆成功！欢迎回来，%s!' % user.username, 'success')
        return redirect(url_for('main.index'))
    else:
        flash(u'登陆失败！用户名或密码错误.', 'danger')
        return render_template('front/login.html')


@main.route('/signin/', methods=["GET", "POST"])
def signin():
    if request.method == "GET":
        return render_template('front/signin.html')
    username = request.form.get("username", None)
    email = request.form.get("email", None)
    password = request.form.get("password", None)
    re_password = request.form.get("re_password", None)
    if not all([username, email, password, re_password]):
        flash(u'用户名和密码不能为空!', 'danger')
        return render_template('front/signin.html')
    if password != re_password:
        flash(u'两次密码不一致！', 'error')
        return redirect(url_for('main.signin'))
    email_user = User.query.filter_by(email=email, is_deleted=0).first()
    name_user = User.query.filter_by(username=username, is_deleted=0).first()
    if email_user:
        flash(u'邮箱已经刚注册！', 'error')
        return redirect(url_for('main.signin'))
    if name_user:
        flash(u'用户名已注册！', 'error')
        return redirect(url_for('main.signin'))
    res, msg, user = User.create({
        "username": username,
        "password_hash": User.hash_password(password),
        "email": email,
        "avatar_hash": User.hash_avatar(email),
    })
    # res, user = User.insert_user(username=username,
    #                              password=password, email=email)
    if res:
        login_user(user)
        try:
            user_ip = request.environ.get('HTTP_X_REAL_IP', request.remote_addr)
            res = requests.get(f"https://ip.taobao.com/service/getIpInfo.php?ip={user_ip}")
            user.update(user.id, {"ip": user_ip})
        except:
            pass
        flash(u'注册成功！欢迎回来，%s!' % user.username, 'success')
        return redirect(url_for('main.index'))
    else:
        flash(u'注册失败！', 'danger')
        return render_template('front/signin.html')


@main.route('/forget/password/', methods=["GET"])
def forget_password():

    return render_template('front/forget_password.html')


@main.route('/logout')
@login_required
def logout():
    logout_user()
    flash(u'您已退出登陆。', 'success')
    return redirect(url_for('main.index'))


@main.route('/upload/', methods=['POST'])
def image_upload():
    try:
        img = request.files.get("file")
        upload_type = Config.UPLOAD_TYPE
        img_name = upload_file(upload_type, img, 'Feedback', conn_bucket)
        print(img_name)
        res = json.dumps({"file_path": img_name, "success": True, "code": 200})
        return res
    except:
        res = json.dumps({"file_path": None, "success": False, "code": 400})
        return res


@main.app_errorhandler(403)
def forbidden(e):
    return render_template('front/403.html'), 403


@main.app_errorhandler(404)
def page_not_found():
    return render_template('front/404.html'), 404


@main.app_errorhandler(500)
def internal_server_error():
    return render_template('front/500.html'), 500


@main.route('/about/')
def about_us():
    """

    :return:
    """
    about = About.query.first()
    return render_template('front/about_us.html', about=about)


@main.route('/friendly/')
def friendly():
    """

    :return:
    """
    return render_template('front/friendly.html')

